﻿using System.Collections.Concurrent;
using System.Threading;
namespace K3Cloud.WebApi.Core.IoC;

/// <summary>
/// IocCallContext&lt;T&gt; 用于在异步/多线程环境下存储和获取与当前上下文相关的数据。
/// 典型用途：
///   - 在 WebApi、后台服务等场景下，存储与当前请求、线程、异步上下文相关的变量（如用户信息、请求ID等）。
///   - 解决 HttpContext.Current/CallContext 在 .NET Core 下不可用的问题。
///   - 线程安全，支持异步流转。
/// 用法示例：
///   IocCallContext&lt;string&gt;.SetData("UserId", "admin");
///   var userId = IocCallContext&lt;string&gt;.GetData("UserId");
/// </summary>
internal static class IocCallContext<T>
{
    // 用于存储每个名称对应的 AsyncLocal<T>，保证数据在异步/线程间隔离
    private static readonly ConcurrentDictionary<string, AsyncLocal<T>> state = new();

    /// <summary>
    /// 设置当前上下文中的数据
    /// </summary>
    /// <param name="name">数据名称（建议唯一）</param>
    /// <param name="data">要存储的数据</param>
    public static void SetData(string name, T data)
    {
        state.GetOrAdd(name, _ => new AsyncLocal<T>()).Value = data;
    }

    /// <summary>
    /// 获取当前上下文中的数据
    /// </summary>
    /// <param name="name">数据名称</param>
    /// <returns>返回存储的数据，若不存在则为 default</returns>
    public static T? GetData(string name)
    {
        return state.TryGetValue(name, out AsyncLocal<T>? data) ? data.Value : default;
    }
}
